/*
ont-space - The ontology-based resource metadata repository
Copyright (c) 2006-2008, Information Eng. Research Unit - Univ. of Alcalá
http://www.cc.uah.es/ie
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.ontspace.util.translator.lom2owl.owl;

import org.ieee.ltsc.lom.LOM;
import org.ieee.ltsc.lom.LOMUtil;

import java.io.*;

import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.RDFNode;
import org.ieee.ltsc.lom.LOM.MetaMetadata.Contribute.Entity;

import org.ietf.mimedir.vcard.*;

/**
 * Translates a LOM meta-metadata element to its representation in OWL.  
 *
 */
public class MD2MDTranslator extends ElementTranslatorImpl {

    private String category =
            new String();
    private String attributeName =
            new String();
    private String element =
            new String();

    private enum CAMPOS {

        FN, N, EMAIL, ORG, OTRO
    }

    /** Creates a new instance of MD2MDTranslator */
    public MD2MDTranslator(String elementCategory, String elementElement,
            String elementAttribute) {

        this.category =
                elementCategory;
        this.attributeName =
                elementAttribute;
        this.element =
                elementElement;

    }

    /**
     * Translates a LOM meta-metadata element to its representation in OWL. 
     * @param lom The metadata record
     * @param ont The ontology
     * @param inst The instance of learning Object
     * @param nsName The namespace
     * @param errorWriter The error file
     */
    public void apply(LOM lom, OntModel ont, Individual inst, String nsName,
            PrintWriter errorWriter) {


        // 1) Get the information from lom xml file
        OntClass lomIdClass =
                ont.getOntClass(nsName + "#lomIdentifier");
        OntClass contributionClass =
                ont.getOntClass(nsName +
                "#metadataContribution");
        OntClass VCardClass =
                ont.getOntClass(nsName + "#vCard");
        OntClass dateTimeClass =
                ont.getOntClass(nsName + "#lomDateTime");
        OntClass langStringClass =
                ont.getOntClass(nsName + "#langString");
        OntClass singleLangStringClass =
                ont.getOntClass(nsName +
                "#singleLangString");

        DatatypeProperty catalogProperty =
                ont.getDatatypeProperty(nsName +
                "#inCatalog");
        DatatypeProperty entryProperty =
                ont.getDatatypeProperty(nsName +
                "#isEntry");
        DatatypeProperty roleProperty =
                ont.getDatatypeProperty(nsName +
                "#hasmetadataContributionRole");
        DatatypeProperty emailProperty =
                ont.getDatatypeProperty(nsName +
                "#hasEmail");
        DatatypeProperty nameProperty =
                ont.getDatatypeProperty(nsName +
                "#hasName");
        DatatypeProperty fNameProperty =
                ont.getDatatypeProperty(nsName +
                "#hasFName");
        DatatypeProperty organizationProperty =
                ont.getDatatypeProperty(nsName +
                "#hasOrganization");
        DatatypeProperty dateTimeProperty =
                ont.getDatatypeProperty(nsName +
                "#hasDateTimeValue");
        DatatypeProperty hasValueProperty =
                ont.getDatatypeProperty(nsName +
                "#hasValue");
        DatatypeProperty inLanguageProperty =
                ont.getDatatypeProperty(nsName +
                "#inLanguage");

        ObjectProperty identifierProperty =
                ont.getObjectProperty(nsName +
                "#hasMetadataIdentifier");
        ObjectProperty contributingProperty =
                ont.getObjectProperty(nsName +
                "#contributingEntity");
        ObjectProperty contributionProperty =
                ont.getObjectProperty(nsName +
                "#metadataHasContribution");
        ObjectProperty includeLangStringProperty =
                ont.getObjectProperty(nsName + "#includesSingleLangString");
        ObjectProperty descriptionProperty =
                ont.getObjectProperty(nsName +
                "#hasDateTimeDescription");
        ObjectProperty contributionDateTimeProperty =
                ont.getObjectProperty(nsName + "#contributionDateTime");

        //3.1 identifier
        String catalogLOM =
                "";
        String entryLOM =
                "";
        int i =
                0;

        String instance =
                null;
        //3.1 identifier
        while (LOMUtil.getMetaMetadataIdentifier(lom, i) != null) {
            catalogLOM =
                    LOMUtil.getCatalog(LOMUtil.getMetaMetadataIdentifier(lom, i));
            entryLOM =
                    LOMUtil.getEntry(LOMUtil.getMetaMetadataIdentifier(lom, i));

            instance =
                    "#idMM" +
                    inst.getLocalName() + "-" + String.valueOf(i);

            Individual lomIdInstance =
                    ont.createIndividual(nsName + instance,
                    lomIdClass);

            inst.setPropertyValue(identifierProperty, lomIdInstance);

            if (catalogLOM != null) {

                RDFNode catalogValue =
                        ont.createTypedLiteral(catalogLOM);
                lomIdInstance.setPropertyValue(catalogProperty, catalogValue);
            }
            if (entryLOM != null) {
                RDFNode entryValue =
                        ont.createTypedLiteral(entryLOM);
                lomIdInstance.setPropertyValue(entryProperty, entryValue);
            }
            i++;
        }

        //3.2 contribute        
        i =
                0;
        while (LOMUtil.getMetaMetadataContribute(lom, i) != null) {
            instance =
                    "#MMC" +
                    inst.getLocalName() + "-" + String.valueOf(i);

            Individual instanceContribution =
                    ont.createIndividual(nsName +
                    instance, contributionClass);
            //3.2.1 role 
            String roleLOM =
                    LOMUtil.getValue(LOMUtil.getMetaMetadataContributeRole(lom,
                    i));
            if (roleLOM != null) {
                RDFNode roleValue =
                        ont.createTypedLiteral(roleLOM);
                instanceContribution.setPropertyValue(roleProperty, roleValue);
            }
            //3.2.2 entity
            int j =
                    0;
            while (LOMUtil.getMetaMetadataContributeEntity(lom, i, j) != null) {
                instance =
                        "#MMvCard" +
                        inst.getLocalName() + "-" + String.valueOf(i);

                Individual VCardInstance =
                        ont.createIndividual(nsName +
                        instance, VCardClass);
                Entity ent =
                        LOMUtil.getMetaMetadataContributeEntity(lom, i, j);
                VCard MimeDirImpl2 =
                        ent.vcard();

                CAMPOS campo =
                        null;

                int lines =
                        MimeDirImpl2.getContentLineCount();

                for (int contador =
                        0; contador < lines; contador++) {

                    String value =
                            MimeDirImpl2.getContentLine(contador).
                            getValueType().
                            toString();

                    if (value.contains("FN:")) {
                        campo =
                                CAMPOS.FN;
                    } else if ((value.contains("N:")) &&
                            !(value.contains("VERSION:"))) {
                        campo =
                                CAMPOS.N;
                    } else if (value.contains("EMAIL:")) {
                        campo =
                                CAMPOS.EMAIL;
                    } else if (value.contains("ORG:")) {
                        campo =
                                CAMPOS.ORG;
                    } else {
                        campo =
                                CAMPOS.OTRO;
                    }

                    switch (campo) {
                        case N:  //Name

                            try {
                                String nameLOM =
                                        value;
                                if (nameLOM != null) {
                                    RDFNode nameValue =
                                            ont.createTypedLiteral(nameLOM);
                                    VCardInstance.setPropertyValue(nameProperty,
                                            nameValue);
                                //System.out.println("N: "+value);
                                }
                            } catch (Exception e) {
                                String log =
                                        "The name field of the Annotation category must contain a value";
                                errorWriter.println(log + '\n' + e);
                            }

                            break;

                        case FN:  //FName

                            try {
                                String fNameLOM =
                                        value;
                                if (fNameLOM != null) {
                                    RDFNode fNameValue =
                                            ont.createTypedLiteral(fNameLOM);
                                    VCardInstance.setPropertyValue(fNameProperty,
                                            fNameValue);
                                //System.out.println("FN: "+value);
                                }
                            } catch (Exception e) {
                                String log =
                                        "The name field of the Annotation category must contain a value";
                                errorWriter.println(log + '\n' + e);
                            }
                            break;


                        case EMAIL:  //Email


                            try {
                                String emailLOM =
                                        value;
                                if (emailLOM != null) {
                                    RDFNode emailValue =
                                            ont.createTypedLiteral(emailLOM);
                                    VCardInstance.setPropertyValue(emailProperty,
                                            emailValue);
                                //System.out.println("EMAIL: "+value);
                                }
                            } catch (Exception e) {
                                String log =
                                        "The Email field of the Annotation category must contain a value";
                                errorWriter.println(log + '\n' + e);
                            }

                            break;

                        case ORG:  //Organization

                            try {
                                String organizationLOM =
                                        value;
                                if (organizationLOM != null) {
                                    RDFNode organizationValue =
                                            ont.createTypedLiteral(organizationLOM);
                                    VCardInstance.setPropertyValue(organizationProperty,
                                            organizationValue);
                                //System.out.println("ORG: "+value);
                                }
                            } catch (Exception e) {
                                String log =
                                        "The Organization field of the Annotation category must contain a value";
                                errorWriter.println(log + '\n' + e);
                            }
                            break;

                        case OTRO:
                            break;


                    }
                }

                instanceContribution.addProperty(contributingProperty,
                        VCardInstance);
                j++;
            }

            //3.2.3 date            
            if (LOMUtil.getMetaMetadataContributeDate(lom, i) != null) {
                instance =
                        "#MMDate" +
                        inst.getLocalName() + "-" + String.valueOf(i);

                Individual instanceDateTime =
                        ont.createIndividual(nsName +
                        instance, dateTimeClass);
                try {
                    String valueLOM =
                            LOMUtil.getString(LOMUtil.getMetaMetadataContributeDate(lom,
                            i).
                            value());
                    if (valueLOM != null) {
                        RDFNode dateValue =
                                ont.createTypedLiteral(valueLOM);
                        instanceDateTime.setPropertyValue(dateTimeProperty,
                                dateValue);
                    }
                } catch (Exception e) {
                }

                //description date                    

                j =
                        0;
                try {
                    if (LOMUtil.getMetaMetadataContributeDate(lom, i).
                            description() != null) {
                        instance =
                                "#lsMMDate" +
                                inst.getLocalName() + "-" + String.valueOf(i);

                        Individual langInstance =
                                ont.createIndividual(nsName +
                                instance, langStringClass);

                        while (LOMUtil.getString(LOMUtil.getMetaMetadataContributeDate(lom,
                                i).description(), j) != null) {
                            instance =
                                    "#slsMMDate" +
                                    inst.getLocalName() + "-" +
                                    String.valueOf(i);

                            Individual singleInstance =
                                    ont.createIndividual(nsName + instance,
                                    singleLangStringClass);

                            String descriptionLOM =
                                    LOMUtil.getString(LOMUtil.getMetaMetadataContributeDate(lom,
                                    i).
                                    description(), j);
                            String languageLOM =
                                    LOMUtil.getLanguage(LOMUtil.getMetaMetadataContributeDate(lom,
                                    i).
                                    description(), j);

                            if (descriptionLOM != null) {
                                RDFNode descriptionValue =
                                        ont.createTypedLiteral(descriptionLOM);
                                singleInstance.setPropertyValue(hasValueProperty,
                                        descriptionValue);
                            }
                            if (languageLOM != null) {
                                RDFNode languageValue =
                                        ont.createTypedLiteral(languageLOM);
                                singleInstance.setPropertyValue(inLanguageProperty,
                                        languageValue);
                            }

                            langInstance.addProperty(includeLangStringProperty,
                                    singleInstance);
                            j++;
                        }
                        instanceDateTime.setPropertyValue(descriptionProperty,
                                langInstance);
                    }
                } catch (Exception e) {
                }

                instanceContribution.setPropertyValue(contributionDateTimeProperty,
                        instanceDateTime);
            }
            inst.addProperty(contributionProperty, instanceContribution);
            i++;

        }//while
        //3.3 metadata schema


        String schemaLOM =
                "";
        DatatypeProperty schemaProperty =
                ont.getDatatypeProperty(nsName +
                "#hasMetadataSchema");

        i =
                0;
        while (LOMUtil.getMetaMetadataMetadataSchema(lom, i) != null) {

            schemaLOM =
                    LOMUtil.getString(LOMUtil.getMetaMetadataMetadataSchema(lom,
                    i));

            if (schemaLOM != null) {
                RDFNode schemaValue =
                        ont.createTypedLiteral(schemaLOM);
                inst.setPropertyValue(schemaProperty, schemaValue);
            }
            i++;
        }


        //3.4 language                 

        DatatypeProperty languageProperty =
                ont.getDatatypeProperty(nsName +
                "#metadataInLanguage");
        String languageLOM =
                LOMUtil.getString(LOMUtil.getMetaMetadataLanguage(lom));
        languageLOM =
                String.valueOf(languageLOM);


        if (languageLOM != null) {
            RDFNode languageValue =
                    ont.createTypedLiteral(languageLOM);
            inst.setPropertyValue(languageProperty, languageValue);
        }




    }
}
